package org.cybzacg.util;

import lombok.extern.slf4j.Slf4j;
import org.cybzacg.convert.context.ConversionContext;

import java.util.function.Supplier;

/**
 * 日志工具类
 * 提供便捷的日志记录方法和性能监控功能
 */
@Slf4j
public class LogUtils {

    /**
     * 记录转换开始日志
     */
    public static void logConversionStart(ConversionContext context, Object source) {
        if (log.isInfoEnabled()) {
            log.info("[CONVERSION_START] {} -> {} | 源值: {}",
                    getTypeName(context.getSourceType()),
                    getTypeName(context.getTargetType()),
                    formatValue(source));
        }
    }

    /**
     * 记录转换成功日志
     */
    public static void logConversionSuccess(ConversionContext context, Object source, Object result) {
        if (log.isInfoEnabled()) {
            log.info("[CONVERSION_SUCCESS] {} -> {} | 源值: {} -> 结果: {}",
                    getTypeName(context.getSourceType()),
                    getTypeName(context.getTargetType()),
                    formatValue(source),
                    formatValue(result));
        }
    }

    /**
     * 记录转换失败日志
     */
    public static void logConversionFailure(ConversionContext context, Object source, Exception exception) {
        if (log.isErrorEnabled()) {
            log.error("[CONVERSION_FAILURE] {} -> {} | 源值: {} | 错误: {}",
                    getTypeName(context.getSourceType()),
                    getTypeName(context.getTargetType()),
                    formatValue(source),
                    exception.getMessage(), exception);
        }
    }

    /**
     * 记录缓存命中日志
     */
    public static void logCacheHit(ConversionContext context, Object source, Object cachedResult) {
        if (log.isDebugEnabled()) {
            log.debug("[CACHE_HIT] {} -> {} | 源值: {} -> 缓存结果: {}",
                    getTypeName(context.getSourceType()),
                    getTypeName(context.getTargetType()),
                    formatValue(source),
                    formatValue(cachedResult));
        }
    }

    /**
     * 记录缓存未命中日志
     */
    public static void logCacheMiss(ConversionContext context, Object source) {
        if (log.isDebugEnabled()) {
            log.debug("[CACHE_MISS] {} -> {} | 源值: {}",
                    getTypeName(context.getSourceType()),
                    getTypeName(context.getTargetType()),
                    formatValue(source));
        }
    }

    /**
     * 记录性能指标
     */
    public static void logPerformance(String operation, long durationMs) {
        if (log.isInfoEnabled()) {
            log.info("[PERFORMANCE] 操作: {} | 耗时: {}ms", operation, durationMs);
        }
    }

    /**
     * 记录方法执行时间
     */
    public static <T> T logExecutionTime(String operation, Supplier<T> supplier) {
        long startTime = System.currentTimeMillis();
        try {
            T result = supplier.get();
            long duration = System.currentTimeMillis() - startTime;
            logPerformance(operation, duration);
            return result;
        } catch (Exception e) {
            long duration = System.currentTimeMillis() - startTime;
            log.error("[PERFORMANCE_ERROR] 操作: {} | 耗时: {}ms | 错误: {}", operation, duration, e.getMessage(), e);
            throw e;
        }
    }

    /**
     * 记录验证成功日志
     */
    public static void logValidationSuccess(Object value, String validator) {
        if (log.isDebugEnabled()) {
            log.debug("[VALIDATION_SUCCESS] 验证器: {} | 值: {}", validator, formatValue(value));
        }
    }

    /**
     * 记录验证失败日志
     */
    public static void logValidationFailure(Object value, String validator, String reason) {
        if (log.isWarnEnabled()) {
            log.warn("[VALIDATION_FAILURE] 验证器: {} | 值: {} | 原因: {}", validator, formatValue(value), reason);
        }
    }

    /**
     * 记录转换器注册日志
     */
    public static void logConverterRegistration(String converterName, Class<?> sourceType, Class<?> targetType) {
        if (log.isInfoEnabled()) {
            log.info("[CONVERTER_REGISTER] 转换器: {} | {} -> {}", 
                    converterName, getTypeName(sourceType), getTypeName(targetType));
        }
    }

    /**
     * 记录转换器卸载日志
     */
    public static void logConverterUnregistration(String converterName, Class<?> sourceType, Class<?> targetType) {
        if (log.isInfoEnabled()) {
            log.info("[CONVERTER_UNREGISTER] 转换器: {} | {} -> {}", 
                    converterName, getTypeName(sourceType), getTypeName(targetType));
        }
    }

    /**
     * 记录调试信息
     */
    public static void logDebug(String message, Object... args) {
        if (log.isDebugEnabled()) {
            log.debug(message, args);
        }
    }

    /**
     * 记录信息
     */
    public static void logInfo(String message, Object... args) {
        if (log.isInfoEnabled()) {
            log.info(message, args);
        }
    }

    /**
     * 记录警告
     */
    public static void logWarn(String message, Object... args) {
        if (log.isWarnEnabled()) {
            log.warn(message, args);
        }
    }

    /**
     * 记录错误
     */
    public static void logError(String message, Object... args) {
        if (log.isErrorEnabled()) {
            log.error(message, args);
        }
    }

    /**
     * 记录错误（带异常）
     */
    public static void logError(String message, Throwable throwable, Object... args) {
        if (log.isErrorEnabled()) {
            log.error(message, args, throwable);
        }
    }

    /**
     * 获取类型名称
     */
    private static String getTypeName(Class<?> type) {
        return type != null ? type.getSimpleName() : "null";
    }

    /**
     * 格式化值输出
     */
    private static String formatValue(Object value) {
        if (value == null) {
            return "null";
        }
        
        String str = value.toString();
        // 限制长度避免日志过长
        if (str.length() > 100) {
            return str.substring(0, 97) + "...";
        }
        return str;
    }

    /**
     * 记录方法调用日志
     */
    public static void logMethodCall(String className, String methodName, Object... args) {
        if (log.isTraceEnabled()) {
            log.trace("[METHOD_CALL] {}.{}({})", className, methodName, formatArgs(args));
        }
    }

    /**
     * 记录方法返回日志
     */
    public static void logMethodReturn(String className, String methodName, Object result) {
        if (log.isTraceEnabled()) {
            log.trace("[METHOD_RETURN] {}.{} -> {}", className, methodName, formatValue(result));
        }
    }

    /**
     * 格式化方法参数
     */
    private static String formatArgs(Object[] args) {
        if (args == null || args.length == 0) {
            return "";
        }
        
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < args.length; i++) {
            if (i > 0) {
                sb.append(", ");
            }
            sb.append(formatValue(args[i]));
        }
        return sb.toString();
    }
}
